import { getNoQueryHash } from 'utils/common'

/**
 * hash变化监听器
 */
export default class HashEventListener {
    /**
     * 当前页面hash
     */
    public curHash = getNoQueryHash()

    /**
     * 模块启用状态的本地存储key
     */
    public static readonly moduleLocalStorageKey = 'screeps-utils-modules'

    constructor(handlers: HashEventHandler[]) {
        this.addHashChangeHandler(handlers)
    }

    /**
     * 监听hash变化
     * @param callback hash变化时的回调
     */
    public onHashChange(callback: (hash: string) => unknown) {
        // 页面初次加载时，触发一次回调
        callback(this.curHash)

        // 创建监听器
        const observer = new MutationObserver(() => {
            const newHash = getNoQueryHash()
            if (newHash !== this.curHash) {
                this.curHash = newHash
                callback(newHash)
            }
        })

        // 启动监听
        observer.observe(document.body, {
            childList: true,
            subtree: true,
        })
    }

    /**
     * 添加hash回调处理器
     */
    public addHashChangeHandler(handlers: HashEventHandler[]) {
        this.onHashChange((hash) => {
            handlers.forEach((handler) => {
                // 该模块未启用
                if (!handler.enable) return
                // hash不匹配
                if (handler.matchHash && !handler.matchHash.test(hash)) return
                // 触发回调
                if (typeof handler.onHashChange === 'function') handler.onHashChange(hash)
            })
        })
    }

    /**
     * 获取模块启用状态
     */
    public static getModuleEnable(moduleName: string) {
        try {
            const moduleInfo = JSON.parse(localStorage.getItem(HashEventListener.moduleLocalStorageKey) || '{}')
            return !!moduleInfo[moduleName]
        } catch (error) {
            console.log(error)
            return false
        }
    }

    /**
     * 设置模块启用状态
     */
    public static setModuleEnable(moduleName: string, enable: boolean) {
        try {
            const moduleInfo = JSON.parse(localStorage.getItem(HashEventListener.moduleLocalStorageKey) || '{}')
            moduleInfo[moduleName] = enable
            localStorage.setItem(HashEventListener.moduleLocalStorageKey, JSON.stringify(moduleInfo))
            return true
        } catch (error) {
            console.log(error)
            return false
        }
    }
}

/**
 * hash变化处理器
 */
export interface HashEventHandler {
    /**
     * 模块名
     */
    moduleName: string

    /**
     * hash变化时的回调
     */
    onHashChange?: (hash: string) => unknown

    /**
     * 匹配hash
     */
    matchHash?: RegExp

    /**
     * 是否启用
     */
    enable: boolean

    /**
     * 本地存储启动状态key
     */
    localStorageKey: string

    /**
     * 设置该模块是否启用
     */
    setEnable: (enable: boolean) => void

    /**
     * 触发该模块面板
     */
    triggerPanel?: () => void
}
